
#if	!defined( __20081117_DEF_WIN_THREAD_H__ )
#define	__20081117_DEF_WIN_THREAD_H__

#include	<assert.h>
#include	<windows.h>

// undefine macros defined in windows.h
#ifdef	max
#undef	max
#endif

#ifdef	min
#undef	min
#endif

namespace PCE_Lib {
namespace CEnv_Def {
namespace PCE_Lib_CurrentCEnvironment {
namespace Tools {

class Thread
{
private:
	static DWORD WINAPI sif_ThreadProc( LPVOID param )
	{
		assert( NotNull( param ) );
		Thread	* p_this = reinterpret_cast< Thread * >( param );
		assert( NotNull( p_this->m_Handle ) );
		DWORD	ret_val = p_this->Entry()  ? 1 : 0;
		// set handle;
		p_this->m_Handle = Null< HANDLE >();	//	= SetNull( p_this->m_Handle ), just to avoid compiler's warning
		return ret_val;
	}
protected:
	virtual bool Sleep( uint32_t usec ) throw()
	{
		assert( NotNull( m_Handle ) );

		pce_usleep( usec );
		return true;
	}
	virtual bool Entry( void ) throw() = 0;
public:
	virtual bool Start( void ) throw()
	{
		HANDLE		thread_handle;
		DWORD		thread_id;

		// create thread
		if( NotNull( m_Handle ) ) {
			return false;
		}
		thread_handle = ::CreateThread(
			Null< LPSECURITY_ATTRIBUTES >(),	// default security attributes
            0,									// use default stack size
            sif_ThreadProc,						// thread function
            this,								// argument to thread function
            CREATE_SUSPENDED,					// use default creation flags
            & thread_id );						// returns the thread identifier
		if( IsNull( thread_handle ) ) {
			return false;
		}
		m_Handle = thread_handle;
		if( -1 == ::ResumeThread( thread_handle ) ) {
			::TerminateThread( thread_handle, 0 );
			m_Handle = Null< HANDLE >();	//	= SetNull( m_Handle ), just to avoid compiler's warning
			return false;
		}
		return true;
	}
	virtual bool IsLive( bool & is_live ) throw()
	{
		is_live = ( Null< HANDLE >() != m_Handle );
		return true;
	}
	virtual bool Stop( void ) throw()
	{
		HANDLE	handle = m_Handle;
		if( IsNull( handle ) ) {
			return true;
		}
		if( 0 == ::TerminateThread( handle, 0 ) ) {
			return false;
		}
		m_Handle = Null< HANDLE >();	//	= SetNull( m_Handle ), just to avoid compiler's warning
		return true;
	}
	virtual bool Join( void ) throw()
	{
		HANDLE	handle = m_Handle;
		if( IsNull( handle ) ) {
			return true;
		}
		return WAIT_OBJECT_0 == ::WaitForSingleObject( handle, INFINITE );
	}
protected:
	Thread( void ) throw() : m_Handle( Null< HANDLE >() ) {}
public:
	virtual ~Thread( void ) throw()
	{
		HANDLE	handle = m_Handle;
		if( NotNull( handle ) ) {
			::WaitForSingleObject( handle, INFINITE );
		}
	}
private:
	volatile HANDLE		m_Handle;
};

}	// Tools
}	// PCE_Lib_CurrentCEnvironment
}	// CEnv_Def
}	// PCE_Lib

#endif	// __20081117_DEF_WIN_THREAD_H__
